package com.jts.cloudspokes.util;

import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.appengine.api.xmpp.JID;
import com.google.appengine.api.xmpp.Message;
import com.jts.cloudspokes.BotConstants;
import com.jts.cloudspokes.entities.BotTaskEntity;

public class BotUtility {
	
	@SuppressWarnings("finally")
	public static long getTaskTime(String taskTime) {
		String userTimeInput = taskTime.trim().toUpperCase();
		System.out.println(userTimeInput);
		int counter = 0, day = 0, hour = 0, min = 0;
		char currentChar;
		boolean charFound = true;
		try {
			while (userTimeInput.length() > 1) {
				currentChar = userTimeInput.charAt(counter);
				charFound = true;
				System.out.println(currentChar);
				switch (currentChar) {
					case 'D':
						day = day + findDuration(currentChar, userTimeInput);
						break;	
					case 'H':
						hour = hour + findDuration(currentChar, userTimeInput);
						break;
					case 'M':
						min  = min + findDuration(currentChar, userTimeInput);
						break;
					default:
						charFound = false;
				}
				if (charFound) {
					userTimeInput = userTimeInput.substring(userTimeInput.indexOf(currentChar) + 1, userTimeInput.length());
					System.out.println(userTimeInput);
					counter = 0;
					continue;
				}
				counter++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			return convertDayToMS(day) + convertHourToMS(hour) + convertMinutesToMS(min); 
		}		
	}
	
	private static int findDuration(char duration, String fullTime) {
		String requiredNumber = fullTime.substring(0, fullTime.indexOf(duration));
		return Integer.parseInt(requiredNumber);
	}
	
	private static long convertDayToMS(long time) {
		return convertHourToMS(time*24);
	}
	
	private static long convertHourToMS(long time) {
		return convertMinutesToMS(time*60);
	}
	
	private static long convertMinutesToMS(long time) {
		return (long)time*60*1000;
	}
	
	public static String getTaskMessage() {
		return null;
	}
	
	public static BotTaskEntity createBotTaskEntityFromMessage(Message message) {
		String messageBody = message.getBody();
		if(!BotUtility.isTaskInFormat(messageBody)) {
			return null;
		}
		JID jid = message.getFromJid();
		String[] messageParts = messageBody.split(" ");
		int mpLength = messageParts.length;
		long countDownMs = 0;
		String taskMessage = ""; 
		for (int mpIndex = 0; mpIndex < mpLength; mpIndex++) {
			String messagePart = messageParts[mpIndex];
			messagePart = messagePart.trim();
			if (messagePart.length() > 0) {
				if (mpIndex == 0) { //time
					//TODO - catch format exception and outofrange exception
					countDownMs = BotUtility.getTaskTime(messagePart);
				} else {
					taskMessage += " " + messagePart;
				}
			}
		}
		taskMessage = taskMessage.trim();
		if (countDownMs != 0 && (taskMessage.trim().length() > 1)) {
			BotTaskEntity bteObj = new BotTaskEntity(jid.getId(), new Date(), countDownMs, taskMessage, true);
			return bteObj;
		}
		return null;
	}
	
	public static String getActualEmailId(String jabberId) {
		if (jabberId == null) {
			return null;
		}
		Pattern pattern = Pattern.compile("/gmail.[a-zA-Z0-9]*");
		Matcher matcher = pattern.matcher(jabberId);
		return matcher.replaceAll("");
	}
	
	private static boolean isTaskInFormat(String message) {
		//Pattern pattern = Pattern.compile("^[\\s]*[0-9]+(.[0-9])*[hmdHMD][\\s][a-zA-Z0-9\\s]+");
		//Pattern pattern = Pattern.compile("^[\\s]*([0-9]+[hmdHMD])+[\\s]*[a-zA-Z0-9\\s]+");
		Pattern pattern = Pattern.compile("^[\\s]*(\\d+[hmdHMD])+[\\s]+(.+)");
		Matcher matcher = pattern.matcher(message);
		return matcher.find();
	}
	
	public static String getDueTime(Date createdDate, long countDownMs) {
		long createdTime = createdDate.getTime();
		long currentTime = System.currentTimeMillis();
		long remainingTime = createdTime + countDownMs - currentTime;
		System.out.println("Remaining time" + remainingTime);
		DueTimeCalculator dtcObj = new BotUtility.DueTimeCalculator(remainingTime);
		dtcObj.calculate();
		return dtcObj.getDueTimeInString();
	}

	private static class DueTimeCalculator {
		long dueTimeInMs;
		int day = 0;
		int hour = 0;
		int min = 0;
		
		public DueTimeCalculator(long dueTimeInMs) {
			this.dueTimeInMs = dueTimeInMs;
		}
		
		public void calculate() {
			day = convertTimeToUnit(BotConstants.DAY_IN_MS);
			hour = convertTimeToUnit(BotConstants.HOUR_IN_MS);
			min = convertTimeToUnit(BotConstants.MIN_IN_MS);
		}
		
		private int convertTimeToUnit(long timeConstant) {
			int count = 0;
			while (dueTimeInMs > timeConstant) {
				count++;
				dueTimeInMs = dueTimeInMs - timeConstant;
			}
			return count;
		}
		
		public String getDueTimeInString() {
			String dueTime = ""; 
			if (day > 0) {
				dueTime = day + "d";
			}
			if (hour > 0) {
				dueTime += hour + "h";
			}
			if (min > 0) {
				dueTime += min + "m";
			} 
			if (dueTime.equals("")) {
				dueTime = "less than 1 minute";
			}
			return dueTime;
		}
	}
}